package com.cacho.s2b.lesson.learn;

import com.cacho.s2b.lesson.utils.Constants;

import com.cacho.s2b.lesson.utils.DealCert;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.joda.time.DateTime;

import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
import java.security.PublicKey;
import java.security.PrivateKey;
import java.security.KeyPairGenerator;
import java.security.cert.X509Certificate;
import java.util.Random;


public class LearnBouncy {
    public static void main(String[] args) throws Exception {
        KeyPair keyPair = generateKey();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
        String javaPrivate = LearnBase64.encode(privateKey.getEncoded());
        DealCert.writeStringToFile(DealCert.saveCert("privateKey", javaPrivate), ".\\key\\java-private.pem");
        String javaPublic = LearnBase64.encode(publicKey.getEncoded());
        DealCert.writeStringToFile(DealCert.saveCert("publicKey", javaPublic), ".\\key\\java-public.pem");
        X509Certificate cert = generateCertificate(publicKey, privateKey); //生成证书
        String input = LearnBase64.encode(cert.getEncoded());
        DealCert.writeStringToFile(DealCert.saveCert("crt", input), ".\\key\\java.crt");
    }
    // import java.security.cert.X509Certificate
    public static X509Certificate generateCertificate(PublicKey publicKey, PrivateKey privateKey) throws Exception {
        JcaX509ExtensionUtils jcaX509ExtensionUtils = new JcaX509ExtensionUtils();
        X509v3CertificateBuilder builder = new JcaX509v3CertificateBuilder(
                new X500Name("C=GB, STREET=London, CN=Konsentus OBIE PSP - 1,O=Konsentus OBIE PSP - 1,OU=Konsentus Testing"), // issuer authority
                BigInteger.valueOf(new Random().nextInt()),
                DateTime.now().toDate(), // start of validity
                new DateTime(2025, 12, 31, 0, 0, 0, 0).toDate(), //end of certificate validity
                new X500Name("C=GB, STREET=London,CN=Konsentus OBIE PSP - 1,O=Konsentus OBIE PSP - 1, OU = Konsentus Testing,organizationIdentifier=PSDXX-TEST-000001"), // subject name of certificate
                publicKey);
        //addExtension(ASN1ObjectIdentifier var1, boolean var2, ASN1Encodable var3)
        builder.addExtension(new ASN1ObjectIdentifier("2.5.4.97"), false, "PSDXX-TEST-000001".getBytes(StandardCharsets.UTF_8));
        builder.addExtension(Extension.authorityInfoAccess,false, "CA Issuers - URI:http://k-test-certificates.s3.eu-west-2.amazonaws.com/scenario_1_qtsp_cert.pem\n".getBytes(StandardCharsets.UTF_8));
        builder.addExtension(Extension.cRLDistributionPoints,false, "URI:http://k-test-certificates.s3.eu-west-2.amazonaws.com/scenario_1_qtsp_crl.der\n".getBytes(StandardCharsets.UTF_8));
        builder.addExtension(Extension.authorityKeyIdentifier, false, jcaX509ExtensionUtils.createAuthorityKeyIdentifier(publicKey));
        builder.addExtension(Extension.subjectKeyIdentifier, false, jcaX509ExtensionUtils.createSubjectKeyIdentifier(publicKey));
        //builder.addExtension(Extension.keyUsage, false, new KeyUsage(KeyUsage.keyCertSign));//KeyUsage
        //builder.addExtension(Extension.basicConstraints, false, new BasicConstraints(true)); //basicConstraints
        builder.addExtension(Extension.qCStatements, true, (new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.3")).intern()); //qCStatements
        return new JcaX509CertificateConverter().getCertificate(builder
                .build(new JcaContentSignerBuilder("SHA256withRSA").build(privateKey)));
    }
    // import java.security.*
    public static KeyPair generateKey() throws Exception {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(Constants.RSA);
        keyPairGenerator.initialize(2048);
        return keyPairGenerator.genKeyPair();
    }

}
